package android.demo.download;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Environment;

public class DownloadFileAsync extends AsyncTask<String, String, String> {
	
	public class DownloadError {
		private String errorMessage = "";
		private String errorCode = "";
		public DownloadError(){
			errorMessage = "";
			errorCode = "";
		}
		public DownloadError(String errorMessage, String errorCode){
			this.errorMessage = errorMessage;
			this.errorCode = errorCode;
		}
		public String getErrorMessage() {
			return errorMessage;
		}
		public void setErrorMessage(String errorMessage) {
			this.errorMessage = errorMessage;
		}
		public String getErrorCode() {
			return errorCode;
		}
		public void setErrorCode(String errorCode) {
			this.errorCode = errorCode;
		}
	}
	
	public abstract class DownloadFileAsyncObserver {
		public abstract void startDownload(int requestCode);
		public abstract void downloadFinish(int requestCode, String filePath);
		public abstract void downloadFailWithError(int requestCode, DownloadError error);
	}
	
	private String fileURL = null;
	private Context context = null;
	private ProgressDialog processDialog = null;
	
	public String getFileURL() {
		return fileURL;
	}

	public void setFileURL(String fileURL) {
		this.fileURL = fileURL;
	}

	public Context getContext() {
		return context;
	}

	public void setContext(Context context) {
		this.context = context;
	}

	public ProgressDialog getProcessDialog() {
		return processDialog;
	}

	public void setProcessDialog(ProgressDialog processDialog) {
		this.processDialog = processDialog;
	}

	public DownloadFileAsync() {
	}

	public DownloadFileAsync(String fileURL) {
		this.fileURL = fileURL;
	}
	
	@Override
	protected String doInBackground(String... parms) {
		int count;
		InputStream input = null;
		OutputStream output = null;
		int lenghtOfFile = 0;
		long total = 0;
		String downloadFilePath = null;
		try {
			URL url = new URL(parms[0]);
			HttpURLConnection conection = ( HttpURLConnection )url.openConnection();
			conection.setConnectTimeout(900000);
			conection.connect();
			int responseCode = conection.getResponseCode();
			if(responseCode!=200){
				final String errorMessage = conection.getResponseMessage();
				conection.disconnect();
				conection = null;
			}
			lenghtOfFile = conection.getContentLength();
			input = new BufferedInputStream(url.openStream());
			
			long externalMemory = DeviceFeatureUtils.getAvailableSpaceOnExternalMemory();
			long internalMemory = DeviceFeatureUtils.getAvailableSpaceOnInternalMemory(context);
			
			if(externalMemory<=0&&internalMemory<=0){
				conection.disconnect();
				conection = null;
				//TODO Bao loi.
				return null;
			}
			
			if(internalMemory>=externalMemory){
				output = context.openFileOutput(fileURL, Context.MODE_PRIVATE);
				File file = context.getFilesDir();
				downloadFilePath = file.getPath() + "/" + fileURL;
			} else {
				File sdCardRoot = Environment.getExternalStorageDirectory();
				File downloadFile = new File(sdCardRoot,fileURL);
				output = new FileOutputStream(downloadFile);
				downloadFilePath = downloadFile.getPath();
			}
			
			byte data[] = new byte[40960];
			total = 0;
			while ( (count = input.read(data)) != -1) {
				total += count;
				output.write(data, 0, count);
			}
			output.flush();
			output.close();
			output = null;
			conection.disconnect();
			conection = null;
			
		}catch (Exception e) {
			e.printStackTrace();
			try{
				context.deleteFile(fileURL);
			} catch (Exception de) {
				de.printStackTrace();
			}
			final String errorMessage = e.getMessage();
			//TODO Bao loi
		} finally {
			
			if(output!=null) try {
				output.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			if(input!=null) try {
				input.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
		}
		return downloadFilePath;
	}

	@Override
	protected void onPostExecute(String downloadFilePath) {
		
	}

	@Override
	protected void onPreExecute() {
		
	}

	protected void onProgressUpdate(String... progress) {
		
	}
}